package com.zc58s.concurrent.redis;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 提供一个Java接口，功能是传来用户ID和时间来预约购票，
 * 可用票量使用redis缓存，用户每天只能预约一次，要求抗住高并发
 */
public class TicketReservationService {
    private final JedisPool jedisPool;

    public TicketReservationService() {
        // 初始化Redis连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(100);    // 最大连接数
        poolConfig.setMinIdle(10);      // 最小空闲连接数
        jedisPool = new JedisPool(poolConfig, "localhost", 6379);
    }


    public void initializeTicketAvailability(LocalDate date, Map<LocalTime, Integer> ticketAvailability) {
        try (Jedis jedis = jedisPool.getResource()) {
            String key = "tickets:" + date.toString();
            Map<String, String> availabilityMap = new HashMap<>();

            for (Map.Entry<LocalTime, Integer> entry : ticketAvailability.entrySet()) {
                LocalTime time = entry.getKey();
                Integer tickets = entry.getValue();
                String field = time.toString();
                String value = tickets.toString();

                availabilityMap.put(field, value);
            }

            jedis.hmset(key, availabilityMap);
        }
    }


    public boolean makeReservation(String userId, LocalDateTime dateTime) {
        LocalDate date = dateTime.toLocalDate();
        LocalTime time = dateTime.toLocalTime();

        try (Jedis jedis = jedisPool.getResource()) {
            String key = "tickets:" + date.toString();
            String field = time.toString();

            // 利用Redis的哈希表来存储每个时间段的可用票量
            // 每个时间段对应的字段名为时间（例如："10:00"）
            // 字段值为可用票量
            String availableTickets = jedis.hget(key, field);

            if (availableTickets != null && Integer.parseInt(availableTickets) > 0) {
                // 用户当天已经预约过了
                if (jedis.sismember("users:" + date.toString(), userId)) {
                    return false;
                }

                // 扣减可用票量
                jedis.hincrBy(key, field, -1);

                // 记录用户已经预约
                jedis.sadd("users:" + date.toString(), userId);

                return true;
            }
        }

        return false;
    }

    public static void main(String[] args) {
        TicketReservationService service = new TicketReservationService();
        LocalDate date = LocalDate.of(2023, 6, 12);
        // 构建初始可用票量映射
        Map<LocalTime, Integer> ticketAvailability = new HashMap<>();
        ticketAvailability.put(LocalTime.of(10, 0), 100);  // 设置10:00的可用票量为100张
        ticketAvailability.put(LocalTime.of(12, 0), 150);  // 设置12:00的可用票量为150张
        // 初始化票量
        service.initializeTicketAvailability(date, ticketAvailability);

        System.out.println("票量初始化成功！");
        String userId = "user123";
        LocalDateTime dateTime = LocalDateTime.of(2023, 6, 12, 10, 0);

        boolean reservationResult = service.makeReservation(userId, dateTime);
        if (reservationResult) {
            System.out.println("预约成功！");
        } else {
            System.out.println("预约失败！");
        }
    }
}